﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Threading.Tasks;
using NLog;

namespace Gollie.Ajax
{
	public class PaymentInfo : AjaxResult
	{
		public string CustomerFullName;
		public string VendorName;
		public string CashierFullName;
		public string CreditString;
		public decimal Credit;
		public string TransactionTicket;
		public bool AllowRefund;

		public PaymentInfo()
			: base(null)
		{ }

		public static PaymentInfo InitPayment(string customerEncodedId, string cashierId)
		{
//			Logger logger = LogManager.GetCurrentClassLogger();

			PaymentInfo paymentInfo = null;
			int errorCode = 0;
			try
			{
				uint c_id = Convert.ToUInt32(cashierId);
				logger.Debug("CustomerID: {0}", customerEncodedId);
				uint cust_id = Hash.Decrypt(customerEncodedId);

				if (cust_id == uint.MaxValue)
				{
					errorCode = 1;
					throw new Exception("Foutieve url-aanroep: ");
				}

				paymentInfo = Database.Queries.GetAjaxPaymentInfo(cust_id, c_id);

				if (paymentInfo.CustomerFullName == null)
				{
					errorCode = 2;
					throw new AjaxException("Deze QR-Code is niet bekend bij Gollie");
				}

				if (paymentInfo.Credit == 0)
				{
					errorCode = 3;
					throw new AjaxException(paymentInfo.CustomerFullName + " heeft geen tegoed bij " + paymentInfo.VendorName);
				}

				PaymentTicket ticket = new PaymentTicket();
				ticket.Populate(cust_id, c_id);

				paymentInfo.TransactionTicket = ticket.ToString();

				//ticket.Store();
			}
			catch (AjaxException fe)
			{
				paymentInfo.ErrorCode = errorCode;
				paymentInfo.ErrorMessage = fe.Message;
			}
			catch (Exception e)
			{
				paymentInfo = new PaymentInfo { CashierFullName = "", Credit = 0, ErrorCode = 99, CustomerFullName = "", ErrorMessage = e.Message };
			}

			return paymentInfo;
		}

		/*
		 * Below works, except for exception handling. And it's slower...
		 * But I learned something...;)
		 *
		public static PaymentInfo InitPaymentThreaded(string customerEncodedId, string cashierId, string origUrl)
		{
			//			Logger logger = LogManager.GetCurrentClassLogger();

			PaymentInfo payment = null;
			int errorCode = 0;
			try
			{
				uint c_id = Convert.ToUInt32(cashierId);
				uint cust_id = 0;
				string decodedCustomerId;

				if (customerEncodedId.StartsWith("0000"))
					decodedCustomerId = customerEncodedId;
				else
					decodedCustomerId = Hash.DescryptToString(Convert.FromBase64String(HttpUtility.UrlDecode(customerEncodedId)));

				if (string.IsNullOrEmpty(decodedCustomerId) || decodedCustomerId.Length != 8 || uint.TryParse(decodedCustomerId, out cust_id) == false)
				{
					errorCode = 1;
					throw new Exception("Foutieve url-aanroep: " + origUrl);
				}

				Func<PaymentInfo> GetPaymentInfo = () =>
					{
						PaymentInfo paymentInfo = Database.Queries.GetAjaxPaymentInfo(cust_id, c_id);
						throw new AjaxException("Deze QR-Code is niet bekend bij Gollie");
						if (paymentInfo.CustomerFullName == null)
						{
							errorCode = 2;
							throw new AjaxException("Deze QR-Code is niet bekend bij Gollie");
						}

						if (paymentInfo.Credit == 0)
						{
							errorCode = 3;
							throw new AjaxException(paymentInfo.CustomerFullName + " heeft geen tegoed bij " + paymentInfo.VendorName);
						}

						return paymentInfo;
					};

				Func<string> GetPaymentTicket = () =>
				{
					PaymentTicket ticket = new PaymentTicket();
					ticket.Populate(cust_id, c_id);

					return ticket.ToString();
				};

				Task[] tasks = new Task[] { Task<PaymentInfo>.Factory.StartNew(GetPaymentInfo), Task<string>.Factory.StartNew(GetPaymentTicket) };
				try
				{
					Task.WaitAll(tasks);
				}
				catch (AggregateException e)
				{
					e.Handle((x) => { return false; });
				}

				payment = ((Task<PaymentInfo>)tasks[0]).Result;

				payment.TransactionTicket = ((Task<string>)tasks[1]).Result;
			}
			catch (AjaxException fe)
			{
				payment.ErrorCode = errorCode;
				payment.ErrorMessage = fe.Message;
			}
			catch (Exception e)
			{
				payment = new PaymentInfo { CashierFullName = "", Credit = 0, ErrorCode = 99, CustomerFullName = "", ErrorMessage = e.Message };
			}

			return payment;
		}
		 */
	}
}